function initialize() {
  var mapDiv = document.getElementById('map-canvas');
  var map = new google.maps.Map(mapDiv, {
    center: new google.maps.LatLng(37.777763, -122.403875),
    zoom: 14,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    mapTypeControlOptions: {
      mapTypeIds: [ 'grey', 'nolabels', 
        google.maps.MapTypeId.ROADMAP,
        google.maps.MapTypeId.HYBRID,
        google.maps.MapTypeId.SATELLITE,
        google.maps.MapTypeId.TERRAIN
      ]
    }
  });

  setupMapStyles(map);
  setupFlickr(map);
}

function getMarkerImage(photo) {
  var url = getFlickrPhotoUrl(photo, 's');
  return new google.maps.MarkerImage(url, null, null, null,
      new google.maps.Size(30, 30));
}

function getFlickrPhotoPage(photo) {
  var url = ['http://www.flickr.com/photos/', photo.owner,
    '/', photo.id].join('');
  return url;
}

function onMarkerClick() {
  var marker = this;
  var photo = marker.photo_;

  var infoWindow = marker.getMap().infoWindow_;
  infoWindow.setContent('<a href="' + getFlickrPhotoPage(photo) + '">' +
    '<img src="' + getFlickrPhotoUrl(photo, 'm') + '">' +
    '</a>');
  infoWindow.setAnchor(marker);
}

/****/

function setupMapStyles(map) {
  var greyStyle = [{
    stylers: [
      { saturation: -100 }
    ]
  }];
  var grey = new google.maps.StyledMapType(greyStyle, {
    name: 'Grey'
  });
  map.mapTypes.set('grey', grey);
  map.setMapTypeId('grey');

  var nolabelStyle = [{
    stylers: [
      { saturation: -100 }
    ]
  },{
    elementType: 'labels',
    stylers: [
      { visibility: 'off' }
    ]
  }];
  var noLabels = new google.maps.StyledMapType(nolabelStyle, {
    name: 'Labels Off'
  });
  map.mapTypes.set('nolabels', noLabels);
}

/**** Everything below from Exercise #2 ****/

function setupFlickr(map) {
  var markerCache = {};
  google.maps.event.addListener(map, 'idle', function() {
    queryFlickr(map.getBounds(), function(result) {
      plotPhotos(result.photos.photo, map, markerCache);
    });
  });

  map.infoWindow_ = new google.maps.InfoWindow({
    map: map
  });
}

function plotPhotos(photos, map, markerCache) {
  for (var i = 0; i < photos.length; i++) {
    var photo = photos[i];

    if (!markerCache[photo.id]) {
      var marker = new google.maps.Marker({
        icon: getMarkerImage(photo),
        position: new google.maps.LatLng(photo.latitude, photo.longitude),
        title: photo.description._content,
        map: map
      });
      marker.photo_ = photo;
      google.maps.event.addListener(marker, 'click', onMarkerClick);
      markerCache[photo.id] = marker;
    }
  }
}

function getFlickrPhotoUrl(photo, size) {
  var url = ['http://farm', photo.farm, '.static.flickr.com/', photo.server,
    '/', photo.id, '_', photo.secret, '_', size, '.jpg'].join('');
  return url;
};


function queryFlickr(bounds, callback) {
  var sw = bounds.getSouthWest();
  var ne = bounds.getNorthEast();

  var bbox = [sw.lng(), sw.lat(), ne.lng(), ne.lat()].join(',');

  var requestUrl = [
    'http://api.flickr.com/services/rest/?method=flickr.photos.search',
    'api_key=' + FLICKR_API_KEY,
    'format=json',
    'jsoncallback=mashupFlickrCallback_',
    'accuracy=16',
    'has_geo=1',
    'per_page=50',
    'sort=date-posted-desc',
    'bbox=' + encodeURIComponent(bbox),
    'extras=geo,description,date_taken'
  ].join('&');

  window.mashupFlickrCallback_ = function(photos) {
    callback(photos);
  };

  getScript(requestUrl);
}

function getScript(src) {
  var script = document.createElement('script');
  script.src = src;
  document.head.appendChild(script);
}

var FLICKR_API_KEY = '1632c18a388a4da173db303dc5d20755';
